import 'package:flutter/material.dart';
import 'package:flutter_form_builder/flutter_form_builder.dart';
import 'package:tdesign_flutter/tdesign_flutter.dart';

import 'default_error.dart';
import 'form_modal.dart';

Widget buildPickerField({
  required FormModal item,
  required GlobalKey<FormBuilderFieldState> fieldKey,
}) {
  return _PickerField(
    item: item,
    fieldKey: fieldKey,
  );
}

class _PickerField extends StatelessWidget {
  const _PickerField({
    required this.item,
    required this.fieldKey,
  });

  final FormModal item;
  final GlobalKey<FormBuilderFieldState> fieldKey;

  List<List<OptionItem>> get _columns => item.options;

  @override
  Widget build(BuildContext context) {
    return FormBuilderField<List<String>>(
      name: item.field,
      key: fieldKey,
      validator: _validateValue,
      builder: (fieldState) {
        final values = fieldState.value ?? const <String>[];
        final text = _formatDisplay(values);
        final hasValue = values.isNotEmpty;

        return GestureDetector(
          behavior: HitTestBehavior.opaque,
          onTap: () => _showPicker(context, fieldState),
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            crossAxisAlignment: CrossAxisAlignment.end,
            children: [
              Text(
                text,
                textAlign: TextAlign.right,
                style: TextStyle(
                  color: hasValue ? Colors.black87 : Colors.grey,
                  fontSize: 14,
                ),
              ),
              if (fieldState.hasError)
                Padding(
                  padding: const EdgeInsets.only(top: 4),
                  child: DefaultError(message: fieldState.errorText ?? ''),
                ),
            ],
          ),
        );
      },
    );
  }

  String? _validateValue(List<String>? value) {
    if (item.require == true && (value == null || value.isEmpty)) {
      return '${item.label}????';
    }
    if (item.validator != null) {
      return item.validator!(value);
    }
    return null;
  }

  String _formatDisplay(List<String> values) {
    if (values.isEmpty) {
      return item.placeholder ?? '???${item.label}';
    }

    final labels = <String>[];
    for (final value in values) {
      OptionItem? found;
      for (final column in _columns) {
        for (final option in column) {
          if (option.value == value) {
            found = option;
            break;
          }
        }
        if (found != null) break;
      }
      labels.add(found?.label ?? value);
    }

    return labels.join(' / ');
  }

  void _showPicker(
    BuildContext context,
    FormFieldState<List<String>> fieldState,
  ) {
    if (_columns.isEmpty) return;

    final currentValues = fieldState.value ?? const <String>[];
    final initialIndexes = _resolveInitialIndexes(currentValues);
    final data = [
      for (final column in _columns) [for (final option in column) option.label],
    ];

    TDPicker.showMultiPicker(
      context,
      title: item.label,
      data: data,
      initialIndexes: initialIndexes,
      onConfirm: (selected) {
        print('selected --------------$selected');
        final indexes = selected.map((value) => value as int).toList();
        final values = _mapIndexesToValues(indexes);
        fieldState.didChange(values);
        Navigator.of(context).pop();
      },
      onCancel: (_) {
        Navigator.of(context).pop();
      },
    );
  }

  List<int> _resolveInitialIndexes(List<String> currentValues) {
    final indexes = <int>[];
    for (var columnIndex = 0; columnIndex < _columns.length; columnIndex++) {
      final column = _columns[columnIndex];
      final value =
          columnIndex < currentValues.length ? currentValues[columnIndex] : null;
      final matchIndex = value == null
          ? -1
          : column.indexWhere((option) => option.value == value);
      indexes.add(matchIndex >= 0 ? matchIndex : 0);
    }
    return indexes;
  }

  List<String> _mapIndexesToValues(List<int> indexes) {
    final values = <String>[];
    for (var columnIndex = 0;
        columnIndex < indexes.length && columnIndex < _columns.length;
        columnIndex++) {
      final column = _columns[columnIndex];
      final optionIndex = indexes[columnIndex];
      if (optionIndex >= 0 && optionIndex < column.length) {
        values.add(column[optionIndex].value);
      }
    }
    return values;
  }
}
